module Control_EX(
    input beq,
    input blt,
    input bltu,
    input [1:0] jump,
    input [2:0] branch,
    input wb_pc_sel,
    input [2:0] wd_sel,
    input [31:0] pc4,
    input [31:0] pcimm,
    input [31:0] imm,
    input [31:0] aluc,
    
    output reg [31:0] wD,
    output [31:0] npc_goto,
    output reg npc_op
    );

    // wd_sel signal
    parameter wd_alu  = 2'b00;
    parameter wd_dram = 2'b01;
    parameter wd_npc  = 2'b10;
    parameter wd_sext = 2'b11;

    // branch signal
    parameter is_beq  =   3'b000;
    parameter is_bne  =   3'b001;
    parameter is_blt  =   3'b100;
    parameter is_bge  =   3'b101;
    parameter is_bltu =   3'b110;
    parameter is_bgeu =   3'b111; 
    parameter is_notB =   3'b010;

    // j signal
    parameter is_jalr = 2'b01;
    parameter is_jal  = 2'b11;
    parameter is_notJ = 2'b00;

    // npc_op control
    always @ (*) begin
        if(jump == is_jalr | jump == is_jal )  npc_op = 1'b1; 
        else begin
            case(branch)
                is_beq:  npc_op =   beq; 
                is_bne:  npc_op =  !beq; 
                is_blt:  npc_op =   blt; 
                is_bge:  npc_op =  !blt; 
                is_bltu: npc_op =  bltu; 
                is_bgeu: npc_op = !bltu;
                default: npc_op =  1'b0;
            endcase
        end
    end
    
    assign npc_goto = (jump == is_jalr) ? { aluc[31:2], 2'b00 } : pcimm;


    // wD control
    wire [31:0] wD_tem = wb_pc_sel ? pcimm : pc4;

    always @ (*) begin
        if(wd_sel[1:0] == wd_sext)         wD = imm;
        else if(wd_sel[1:0] == wd_alu)     wD = aluc;
        else                               wD = wD_tem;
    end
    
endmodule
